package com.kun.utils;

import com.kun.enums.DirectionEnum;
import com.kun.enums.OrderEnum;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 检查/校验
 */
public class CheckUtil {

    private static String DIGIT_REG = "[0-9]*";

    /**
     * 检查用户输入的命令集是否合法
     * @param inputCommands
     * @return
     */
    public static boolean isCommandsValid(String[] inputCommands){
        if (inputCommands == null || inputCommands.length == 0){
            return false;
        }
        int borderX = 0;
        int borderY = 0;
        for (int i = 0; i < inputCommands.length; i++) {
            String command = inputCommands[i];
            if (i == 0){
                // 1.1 第一行要是数字
                if (!isNumeric(command)){
                    throw new RuntimeException("第一行要为数字...");
                }
                // 1.2 第一行至少两个参数
                String[] xy = command.split(" ");
                if (xy.length < 2){
                    throw new RuntimeException("第一行至少两个参数...");
                }
                // 1.3 边界值要合法
                if(!isBorderValid(Integer.parseInt(xy[0]),Integer.parseInt(xy[1]))){
                    throw new RuntimeException("边界值不合法...");
                }
                borderX = Integer.parseInt(xy[0]);
                borderY = Integer.parseInt(xy[1]);
            }else if (i%2 != 0){
                // 3. 如果i为奇数 则必须为 数字 数字 字母
                String[] dds = command.split(" ");
                if (dds.length < 3){
                    throw new RuntimeException("奇数行至少三个参数...");
                }
                if (!isNumeric(dds[0])||!isNumeric(dds[1])||!isDirectionValid(dds[2])){
                    throw new RuntimeException("奇数行为数字 数字 字母...");
                }
                if(isOutOfBorder(Integer.parseInt(dds[0]),borderX) || isOutOfBorder(Integer.parseInt(dds[1]),borderY)){
                    throw new RuntimeException("火星车被放到了黑洞...");
                }

            }else{
                // 4. 如果i-行为偶数 则必须在规定的字符内
                if (!isOrdersValid(command)){
                    throw new RuntimeException("出现了预料之外的命令，我没法执行...");
                }
            }
        }
        return true;
    }

    /**
     * 判断方向是否合法
     * @param direction
     * @return
     */
    private static boolean isDirectionValid(String direction){
        for (DirectionEnum e : DirectionEnum.values()) {
            if (e.getDirection().equals(direction)){
                return true;
            }
        }
        return false;
    }


    /**
     * 判断指令是否合法
     * @param order
     * @return
     */
    private static boolean isOrderValid(String order){
        if (order == null || order.length() == 0){
            return false;
        }
        for (OrderEnum e : OrderEnum.values()) {
            if (e.getOrder().equals(order)){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断指令集是否合法
     * @param order
     * @return
     */
    private static boolean isOrdersValid(String order){
        if (order == null || order.length() == 0){
            return false;
        }
        for (int i = 0; i < order.length(); i++) {
            String s = String.valueOf(order.charAt(i));
            if (s == null || "".equals(s)){
                continue;
            }
            if(!isOrderValid(s)){
                return false;
            }
        }
        return true;
    }

    /**
     * 校验输入的边界是否合法
     * @param borderX
     * @param borderY
     * @return
     */
    private static boolean isBorderValid(int borderX,int borderY){
        if(borderX <=0 || borderY <=0){
            return false;
        }
        return true;
    }

    /**
     * 判断字符串是否是由数字组成
     * @param str
     * @return
     */
    public static boolean isNumeric(String str){
        if (str == null || str.trim().equals("")){
            return false;
        }
        Pattern pattern = Pattern.compile(DIGIT_REG);
        Matcher isNum = pattern.matcher(str.trim().replace(" ","").replace("-",""));
        if( !isNum.matches() ){
            return false;
        }
        return true;
    }

    /**
     * 判断是否超过边界
     * @param pos
     * @param border
     * @return
     */
    public static boolean isOutOfBorder(int pos,int border){
        if (pos > border){
            return true;
        }
        return false;
    }

}
